package com.pi.wms.service;

import com.pi.common.CodesConstants;
import com.pi.core.service.UserAccessUtils;
import com.pi.framework.core.util.ConvertUtils;
import com.pi.framework.core.util.SecurityUtils;
import com.pi.framework.core.util.StringUtils;
import com.pi.framework.pro.GenericCrudService;
import com.pi.framework.pro.IGenericRepository;
import com.pi.pro.xcmg.am.common.XcmgAmConstants;
import com.pi.sys.service.UserDivisionService;
import com.pi.wms.common.WmsConstants;
import com.pi.wms.common.WmsTextUtils;
import com.pi.wms.entity.*;
import com.pi.wms.repository.SoRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.*;


@Service("WMSSMSOSERVICE")
@Transactional
@Slf4j
public class SmSoService extends BaseSoService<TwaDocSoHeader, Long>{

	@Override
	protected IGenericRepository<TwaDocSoHeader,Long> getRepository() {
		return this.repository;
	}


	@Override
	protected Predicate toPredicate(Root<TwaDocSoHeader> root, CriteriaQuery<?> cq, CriteriaBuilder cb, Map<String, ?> query) {
		List<Predicate> list = new ArrayList<Predicate>();
		
		//this.toPredicateTextLike(root, cq, cb, query, "documentNumber", list);
		this.toPredicateSelectEquals(root, cq, cb, query, "type", list);
		this.toPredicateSelectEquals(root, cq, cb, query, "status", list);

        list.add(cb.equal(root.get("category"), XcmgAmConstants.WORK_SOURCE_SELF_MADE));

		String material = (String) query.get("material");
		if (!StringUtils.isNullOrBlank(material)) {
			//list.add(cb.equal(root.get("details.materialCode"), material));
			Join<TwaDocSoDetails, TwmBasMaterial> materialJoin = root.join("details").join("material");
			list.add(cb.or(cb.like(materialJoin.get("code"), "%" + material.trim() + "%"), cb.like(materialJoin.get("name"), "%" + material.trim() + "%")));
		}

		String docno = (String) query.get("docnum");
		if (!StringUtils.isNullOrBlank(docno)) {
			list.add(cb.or(cb.like(root.get("documentNumber"), "%" + docno + "%"), cb.like(root.get("refDocNumber"), "%" + docno + "%")));
		}

		//
		String consignee = (String) query.get("consignee");
		if (!StringUtils.isNullOrBlank(consignee)) {
            consignee=consignee.trim();
			list.add(cb.or(cb.like(root.get("consigneeCode"), "%" + consignee + "%"), cb.like(root.get("consigneeName"), "%" + consignee + "%")));
		}

        String refdocnum = (String) query.get("refdocnum");
        if (!StringUtils.isNullOrBlank(refdocnum)) {
            list.add(cb.or(cb.like(root.get("refDocNumber"), "%" + refdocnum + "%"),
                           cb.like(root.get("refMoNumber"),  "%" + refdocnum + "%"),
                           cb.like(root.get("refAsnNumber"),  "%" + refdocnum + "%"),
                           cb.like(root.get("refSoNumber"),  "%" + refdocnum + "%")) );
        }
        //
        String payterm = (String) query.get("payterm");
        if (!StringUtils.isNullOrBlank(payterm)) {
            list.add(cb.or(cb.like(root.get("paymentTerms"), "%" + payterm + "%")));
        }
        //
        String planplace = (String) query.get("planplace");
        if (!StringUtils.isNullOrBlank(planplace)) {
            list.add(cb.or(cb.like(root.get("planLoadPlace"), "%" + planplace + "%"),
                    cb.like(root.get("planLoadDoor"),  "%" + planplace + "%")));
        }

        String deliveryplace = (String) query.get("deliveryplace");
        if (!StringUtils.isNullOrBlank(deliveryplace)) {
            list.add(cb.or(cb.like(root.get("deliveryFromPlace"), "%" + deliveryplace + "%"),
                    cb.like(root.get("deliveryDischargePlace"),  "%" + deliveryplace + "%"),
                    cb.like(root.get("deliveryTerms"),  "%" + deliveryplace + "%"))
            );
        }

        String deliverynum = (String) query.get("deliverynum");
        if (!StringUtils.isNullOrBlank(deliverynum)) {
            list.add(cb.or(cb.like(root.get("deliveryShipNum"), "%" + deliverynum + "%"),
                    cb.like(root.get("deliveryContainerNum"),  "%" + deliverynum + "%"),
                    cb.like(root.get("deliveryTerms"),  "%" + deliveryplace + "%")));
        }


        boolean linecheck=false;
        if (!StringUtils.isNullOrBlank(refdocnum)) {
            linecheck=true;
        }
        String reflotnum = (String) query.get("reflotnum");
        if (!StringUtils.isNullOrBlank(reflotnum)) {
            linecheck=true;
        }
        String uloc = (String) query.get("uloc");
        if (!StringUtils.isNullOrBlank(uloc)) {
            linecheck=true;
        }
        String sloc = (String) query.get("sloc");
        if (!StringUtils.isNullOrBlank(sloc)) {
            linecheck=true;
        }
        String containnumber = (String) query.get("containnumber");
        if (!StringUtils.isNullOrBlank(containnumber)) {
            linecheck=true;
        }

        if (linecheck){
            Join<TwaDocSoHeader, TwaDocSoDetails> detailsJoin = root.join("details");
            //批次
            if (!StringUtils.isNullOrBlank(reflotnum)) {
                list.add(cb.and(cb.like(detailsJoin.get("dEdi07"), "%" + reflotnum.trim() + "%")));
            }
            //工位
            if (!StringUtils.isNullOrBlank(uloc)) {
                list.add(cb.and(cb.like(detailsJoin.get("dEdi12"), "%" + uloc.trim() + "%")));
            }
            //配盘点
            if (!StringUtils.isNullOrBlank(sloc)) {
                list.add(cb.and(cb.like(detailsJoin.get("dEdi12"), "%" + sloc.trim() + "%")));
            }
            //托盘
            if (!StringUtils.isNullOrBlank(containnumber)) {
                list.add(cb.and(cb.like(detailsJoin.get("checkContainNumber"), "%" + containnumber.trim() + "%")));
            }
        }

        //
		Date date=null;
		String fromdate = (String) query.get("fromdate");
		if (!StringUtils.isNullOrBlank(fromdate)) {
			date = WmsTextUtils.plainDate(fromdate,true);
			if (date!=null){
				list.add(cb.greaterThanOrEqualTo(root.get("createdDate"), date));
			}
		}
		String todate = (String) query.get("todate");
		if (!StringUtils.isNullOrBlank(todate)) {
			date = WmsTextUtils.plainDate(todate,false);
			if (date!=null){
				list.add(cb.lessThanOrEqualTo(root.get("createdDate"), date));
			}
		}

		//
		String[] incltypes = ConvertUtils.convertToStringArray(query.get("includeTypes"));
		List<String> indoctypes=null;
		if (incltypes != null) {
			indoctypes = Arrays.asList(incltypes);
			if (indoctypes != null && indoctypes.size() > 0) {
				Predicate p = root.get("type").in(indoctypes);
                list.add(cb.and(p));
			}
		}
		String[] excltypes = ConvertUtils.convertToStringArray(query.get("excludeTypes"));
		List<String> exdoctypes=null;
		if (excltypes != null) {
			exdoctypes = Arrays.asList(excltypes);
			if (exdoctypes != null && exdoctypes.size() > 0) {
				Predicate p = root.get("type").in(exdoctypes);
                list.add(cb.and(cb.not(p)));
			}
		}

        //页面选择
        Long divisionid= UserAccessUtils.getCurrentDivision();
        if ((divisionid!=null) && (divisionid>0L)){
            list.add(cb.equal(root.get("divisionId"), divisionid));
        }
        //权限控制
        List<Long> userDivisionIds = this.userDivisionService.findIdsByUsersId(SecurityUtils.getLoginUserId());
        if ((userDivisionIds!=null)&&(userDivisionIds.size()>0)){
            Predicate p = root.get("divisionId").in(userDivisionIds);
            list.add(cb.and(p));
        }

		String option=CodesConstants.COMMON_FLAG_NO;
		if (query.get(WmsConstants.DOCUMENT_QUERY_OPTION)!=null){
			option=(String)query.get(WmsConstants.DOCUMENT_QUERY_OPTION);
			option=option.trim();
		}
		String status = (String) query.get("status");
		if ( (status!=null) &&
                ((WmsConstants.SO_STATUS_CLOSE.equalsIgnoreCase(status))||(WmsConstants.SO_STATUS_CANCELL.equalsIgnoreCase(status)))){
            option= WmsConstants.DOCUMENT_QUERY_OPTION_SHOWALL;
		}
		if (!option.equalsIgnoreCase(WmsConstants.DOCUMENT_QUERY_OPTION_SHOWALL)){
			list.add(cb.notEqual(root.get("status"), WmsConstants.SO_STATUS_CLOSE));
			list.add(cb.notEqual(root.get("status"), WmsConstants.SO_STATUS_CANCELL));
		}

		Predicate[] p = new Predicate[list.size()];
		return cb.and(list.toArray(p));
	}


	@Override
	protected void preSave(TwaDocSoHeader so){
		if (so==null){
			return;
		}
		if (!so.isNew()){
			return;
		}
		//
		if (so.getGlobalClientId()==null){
			so.setGlobalClientId(wmsClientConfig.globalClientid());
		}
		if (so.getCustomerId()==null){
			so.setCustomerId(wmsClientConfig.customerid());
		}

		if (so.getDivisionId()==null){
			so.setDivisionId(wmsClientConfig.divisionid());
		}
		//
		String docnum="";
		if (StringUtils.isNullOrBlank(so.getDocumentNumber())){
			docnum=sequenceService.next(WmsConstants.SEQUENCE_NAME_DOC_SO);
			if (StringUtils.isNullOrBlank(docnum)){
				docnum= WmsTextUtils.genTransNumber("A","");
			}
			so.setDocumentNumber(docnum);
		}
		//
		if (so.getConsigneeId()!=null){
			Optional<TwmBasCustomer> su =customerRepository.findById(so.getConsigneeId());
			if (su.get()!=null){
				so.setConsigneeCode(su.get().getCode());
				so.setConsigneeName(su.get().getName());
			}
		}
		so.setDelFlag(false);
		so.setEditable(true);
		so.setEnabled(true);
		so.setCategory(XcmgAmConstants.WORK_SOURCE_SELF_MADE);

		//Status=0000
		Map<String,String> defValues=new HashMap<String,String>();
		defValues.put("type", WmsConstants.SO_TYPE_WORK_ORDER);
		defValues.put("status", WmsConstants.SO_STATUS_CREATE);
		defValues.put("qcStatus", WmsConstants.QUALITY_STATUS_PASS);
		defValues.put("releaseStatus", CodesConstants.COMMON_RELEASE_STATUS_CREATED);
		defValues.put("printStatus", CodesConstants.COMMON_FLAG_NO);
		StringUtils.ifNull(so, defValues);
	}
}
